#
# Copyright (c) 2024 Ingenic Semiconductor Co.,Ltd
# Author: Keven <keven.ywhan@ingenic.com>
#
# Find out source, build, and install directories
SDK_DIR = $(CURDIR)/../..
BUILD_DIR = build

include $(SDK_DIR)/config.mk

SPL_PATH = spl
CORE_PATH = freeRTOS
ARCH_PATH = arch/$(ARCH)/$(CPU)
SOC_PATH = arch/$(SOC)
SAMPLE_PATH = .

######################################
# target
######################################
TARGET = template

######################################
# building variables
######################################
# debug build?
DEBUG = 0

# optimization
OPT = -fpie -fno-builtin -fomit-frame-pointer -Wall -nostdlib -Werror-implicit-function-declaration

######################################
# source
######################################
# Setup list of objects
libcore-object-mks=$(shell if [ -d $(SDK_DIR)/$(CORE_PATH)/ ]; then find $(SDK_DIR)/$(CORE_PATH) -iname "objects.mk" | sort -r; fi)
libarch-object-mks=$(shell if [ -d $(SDK_DIR)/$(ARCH_PATH)/ ]; then find $(SDK_DIR)/$(ARCH_PATH) -iname "objects.mk" | sort -r; fi)
libsoc-object-mks=$(shell if [ -d $(SDK_DIR)/$(SOC_PATH)/ ]; then find $(SDK_DIR)/$(SOC_PATH) -iname "objects.mk" | sort -r; fi)
libsample-object-mks=$(shell find $(SAMPLE_PATH) -iname "objects.mk" | sort -r)

include $(libcore-object-mks)
include $(libarch-object-mks)
include $(libsoc-object-mks)
include $(libsample-object-mks)

# Setup list of objects
libriscv-objs-path-y=$(foreach obj,$(libcore-objs-y),$(BUILD_DIR)/$(CORE_PATH)/$(obj))
libriscv-objs-path-y+=$(foreach obj,$(libarch-objs-y),$(BUILD_DIR)/$(ARCH_PATH)/$(obj))
libriscv-objs-path-y+=$(foreach obj,$(libsoc-objs-y),$(BUILD_DIR)/$(SOC_PATH)/$(obj))
libriscv-objs-path-y+=$(foreach obj,$(libsample-objs-y),$(BUILD_DIR)/$(obj))

#$(error "$(src-objs-path-y), $(libriscv-objs-path-y)")

#######################################
# binaries
#######################################
# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
# either it can be added to the PATH environment variable.
ifdef GCC_PATH
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)as
LD = $(GCC_PATH)/$(PREFIX)ld
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
AR = $(GCC_PATH)/$(PREFIX)ar
READELF = $(GCC_PATH)/$(PREFIX)readelf
OBJDUMP = $(GCC_PATH)/$(PREFIX)objdump
else
CC = $(PREFIX)gcc
AS = $(PREFIX)as
LD = $(PREFIX)ld
CP = $(PREFIX)objcopy
SZ = $(PREFIX)size
AR = $(PREFIX)ar
READELF = $(PREFIX)readelf
OBJDUMP = $(PREFIX)objdump
endif
BIN = $(CP) -O binary -S

#######################################
# CFLAGS
#######################################
# cpu
CPUFLAGS = -march=rv32gc -mabi=ilp32d -Wno-abi

# fpu
FPU =

# float-abi
FLOAT-ABI =

# mcu
#MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
MCU = $(CPUFLAGS) $(FPU) $(FLOAT-ABI)

# macros for gcc
# AS defines
AS_DEFS = -D_ASSEMBLER_ -D__ASSEMBLY__

# C defines
C_DEFS =

# AS includes
AS_INCLUDES = \
-I$(CORE_PATH)/include

# C includes
C_INCLUDES =	\
-Iinclude  \
-I$(SDK_DIR)/$(CORE_PATH)/include \
-I$(SDK_DIR)/$(ARCH_PATH)/include \
-I$(SDK_DIR)/$(SOC_PATH)/include

# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections -static

CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections -static

ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2 -O0
else
CFLAGS += -O2
endif

# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"

ARFLAGS	= rcs

#######################################
# LDFLAGS
#######################################
LDSCRIPT = $(CURDIR)/target.ld
# libraries
ifdef GCC_PATH
LIBDIR = -L$(GCC_PATH)/../riscv32-unknown-elf/lib
else
$(error "$(LD) need to set the path of the lib")
endif
LIBS = -lc -lm -lnosys
# LIBDIR = -L/home_a/ywhan/toolchain/riscv32-ingenic-v1-elf-tools-r0.0.5/riscv32-unknown-elf/lib
# LDFLAGS = $(CFLAGS) -T$(LDSCRIPT) -Wl,--whole-archive -Wl,--no-whole-archive -fpie
LDFLAGS = -T$(LDSCRIPT) $(LIBDIR) $(LIBS)

# default action: build all
all: spl $(TARGET).elf $(TARGET).bin tmpfiles

spl:
	$(MAKE) -C $(SDK_DIR)/$(SPL_PATH)

#######################################
# build the application
#######################################
OBJECTS=$(libriscv-objs-path-y)

$(BUILD_DIR)/%.o: $(SDK_DIR)/%.c  Makefile | $(BUILD_DIR)
	mkdir -p $(dir $@)
	$(CC) -c $(CFLAGS) $< -o $@

$(BUILD_DIR)/%.o: $(SDK_DIR)/%.S  Makefile | $(BUILD_DIR)
	mkdir -p $(dir $@)
	$(CC) -c $(ASFLAGS) -o $@ $<

$(BUILD_DIR)/%.o: %.c  Makefile | $(BUILD_DIR)
	mkdir -p $(dir $@)
	$(CC) -c $(CFLAGS) $< -o $@

$(BUILD_DIR)/%.o: %.S  Makefile | $(BUILD_DIR)
	mkdir -p $(dir $@)
	$(CC) -c $(ASFLAGS) -o $@ $<

$(TARGET).elf: $(OBJECTS)
	$(LD) $(OBJECTS) $(LDFLAGS) -o $@
	$(SZ) $@

$(TARGET).bin: $(TARGET).elf $(SDK_DIR)/$(SPL_PATH)/spl-pad.bin
	$(BIN) $(TARGET).elf $(TARGET).bin
	cat $(SDK_DIR)/$(SPL_PATH)/spl-pad.bin $(TARGET).bin > $(TARGET)-spl.bin

$(BUILD_DIR):
	mkdir $@

.PHONY: clean

#######################################
# clean up
#######################################
clean:
	$(MAKE) -C $(SDK_DIR)/$(SPL_PATH) clean
	rm -fR $(BUILD_DIR)
	find $(CURDIR) -type f \( -name "*.elf" -o -name "$(TARGET).*" -o -name "*.bin" \) -exec rm -rf {} +
	find $(CURDIR) -type f -name "*.map" -exec rm -rf {} +
	find $(CURDIR) -type f -name "all" -exec rm -rf {} +

tmpfiles: $(TARGET).elf
	@$(READELF) -a $< > $(TARGET).readelf
	@$(OBJDUMP) -d $< > $(TARGET).dump
#######################################
# dependencies
#######################################
-include $(wildcard $(BUILD_DIR)/*.d)

# *** EOF ***
